﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Threading;
using System.Collections;

namespace SqlMiM.Common.UserControls.PerfGraph
{
    public class HistoryGraphGroup : DispatcherObject, ICollection<HistoryGraph>, IEnumerable<HistoryGraph>, IEnumerable
    {


        // Methods
        public HistoryGraphGroup()
            : this(TimeSpan.FromSeconds(1.0))
        {
        }

        public HistoryGraphGroup(TimeSpan updateInterval)
        {
            this.UpdateTimer = new DispatcherTimer(updateInterval, DispatcherPriority.Normal, new EventHandler(this.UpdateData), base.Dispatcher);
            this.UpdateTimer.IsEnabled = false;
            this.Children = new List<HistoryGraph>();
        }

        public void Add(HistoryGraph item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }
            item.Group = this;
        }

        public void Clear()
        {
            this.Pause();
            while (this.Children.Count > 0)
            {
                this.Children[0].Group = new HistoryGraphGroup(this.UpdateInterval);
            }
        }

        public void ClearData()
        {
            this.ClearData(false);
        }

        public void ClearData(bool removeHistoryData)
        {
            for (int i = 0; i < this.Children.Count; i++)
            {
                this.Children[i].ClearData(removeHistoryData);
            }
        }

        public bool Contains(HistoryGraph item)
        {
            return this.Children.Contains(item);
        }

        public void CopyTo(HistoryGraph[] array, int arrayIndex)
        {
            this.Children.CopyTo(array, arrayIndex);
        }

        public void Pause()
        {
            if (this.UpdateTimer.IsEnabled)
            {
                this.UpdateTimer.Stop();
            }
        }

        public bool Remove(HistoryGraph item)
        {
            bool flag = false;
            if (this.Contains(item))
            {
                item.Group = new HistoryGraphGroup(this.UpdateInterval);
                flag = true;
            }
            return flag;
        }

        public void Start()
        {
            if (!this.UpdateTimer.IsEnabled && (this.Children.Count > 0))
            {
                this.UpdateTimer.Start();
            }
        }

        public void Stop()
        {
            this.Pause();
            this.ClearData(true);
            for (int i = 0; i < this.Children.Count; i++)
            {
                this.Children[i].StopRunning();
            }
            this.HasUpdated = false;
        }

        internal void SwitchGroup(HistoryGraph historyGraph)
        {
            if (historyGraph == null)
            {
                throw new ArgumentNullException("historyGraph");
            }
            HistoryGraphGroup group = historyGraph.Group;
            if (group != this)
            {
                if (group != null)
                {
                    if (!group.Children.Remove(historyGraph))
                    {
                        throw new ArgumentException("'oldGroup' did not contain the specified HistoryGraph");
                    }
                    if (group.Count == 0)
                    {
                        group.Pause();
                    }
                }
                this.Children.Add(historyGraph);
                if (this.HasUpdated)
                {
                    historyGraph.StartRunning(this.FirstUpdate);
                }
                else if (!this.UpdateTimer.IsEnabled)
                {
                    historyGraph.StopRunning();
                }
            }
        }

        IEnumerator<HistoryGraph> IEnumerable<HistoryGraph>.GetEnumerator()
        {
            return this.Children.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.Children.GetEnumerator();
        }

        private void UpdateData(object sender, EventArgs e)
        {
            this.UpdateTimer.Stop();
            if (!this.HasUpdated)
            {
                this.FirstUpdate = DateTime.UtcNow;
                this.LastUpdate = this.FirstUpdate;
                this.HasUpdated = true;
                for (int j = 0; j < this.Children.Count; j++)
                {
                    this.Children[j].StartRunning(this.FirstUpdate);
                }
            }
            else
            {
                TimeSpan span = (TimeSpan)(DateTime.UtcNow - this.LastUpdate);
                long num2 = span.Ticks / this.UpdateInterval.Ticks;
                this.LastUpdate += TimeSpan.FromTicks(this.UpdateInterval.Ticks * num2);
            }
            for (int i = 0; i < this.Children.Count; i++)
            {
                this.Children[i].UpdateData(this.LastUpdate);
            }
            this.UpdateTimer.Start();
        }

        // Properties
        private List<HistoryGraph> Children
        {
            get;
            set;
        }

        public int Count
        {
            get
            {
                return this.Children.Count;
            }
        }

        private DateTime FirstUpdate
        {
            get;
            set;
        }

        private bool HasUpdated
        {
            get;
            set;
        }

        private DateTime LastUpdate
        {
            get;
            set;
        }

        bool ICollection<HistoryGraph>.IsReadOnly
        {
            get
            {
                return false;
            }
        }

        public TimeSpan UpdateInterval
        {
            get
            {
                return this.UpdateTimer.Interval;
            }
            set
            {
                this.UpdateTimer.Interval = value;
            }
        }

        private DispatcherTimer UpdateTimer
        {
            get;
            set;

        }
    }


}
